using System;

namespace LazyLoadDotNet.Domain
{
    public abstract class GhostObject<T> : MarshalByRefObject  where T : IGhostable
    {
        private readonly object GHOST = new object();
        private readonly object LOADING = new object();
        private readonly object LOADED = new object();
        private object status;

        protected GhostObject()
        {
            status = GHOST;
        }                

        public bool IsGhost
        {
            get { return status == GHOST; }
        }

        public bool IsLoading
        {
            get { return status == LOADING; }
        }

        public void MarkLoaded()
        {
            status = LOADED;
        }

        public void MarkLoading()
        {
            status = LOADING;
        }
        
        public void Load(IGhostable subject)
        {
            ILoader<T> loader = LoaderRegistry.GetLoader<T>();
            subject.MarkLoading();
            loader.Load((T) subject);
            subject.MarkLoaded();            
        }

        public static T CreateGhost(int id)
        {
            return  (T) new LazyLoadProxy(id, typeof(T)).GetTransparentProxy();
        }        
    }
}